﻿// CLogDialog.cpp: 实现文件
//

#include "pch.h"
#include "HCViewerProgramm.h"
#include "afxdialogex.h"
#include "CLogDialog.h"
#include <fstream>
#include <time.h>
#include <regex>
using namespace std;
extern ofstream out;
// CLogDialog 对话框

IMPLEMENT_DYNAMIC(CLogDialog, CDialogEx)

CLogDialog::CLogDialog(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_DIALOG_LOG, pParent)
{
	m_SearchIndex = 0;
	m_FilterLevel = 0;
}
CLogDialog::CLogDialog(CWnd* pParent , string fileDir)
	: CDialogEx(IDD_DIALOG_LOG, pParent), m_FileDir(fileDir)
{
	m_SearchIndex = 0;
	m_FilterLevel = 0;
}
CLogDialog::~CLogDialog()
{
}

void CLogDialog::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	//DDX_Control(pDX, IDC_COMBO_LEVEL, m_ComboLevel);
	DDX_Control(pDX, IDC_EDIT_SEARCH, M_EditSearch);
	DDX_Control(pDX, IDC_BUTTON_SEARCH, m_SearchBtn);
	DDX_Control(pDX, IDC_LIST_REPORT, m_LogViewList);
	//DDX_Control(pDX, IDC_BUTTON_NEXT, m_SearchNext);
	DDX_Control(pDX, IDC_CHECK_ERROR, m_RadioError);
	DDX_Control(pDX, IDC_CHECK_DEBUG, m_RadioDebug);
	DDX_Control(pDX, IDC_CHECK_INFO, m_RadioInfo);
	DDX_Control(pDX, IDC_CHECK_ALL, m_RadioAll);
	DDX_Control(pDX, IDC_CHECK_IMPORTANT, m_RadioImport);
	DDX_Control(pDX, IDC_STATIC_RESULT, m_StaticResult);
}


BEGIN_MESSAGE_MAP(CLogDialog, CDialogEx)
	ON_BN_CLICKED(IDC_BUTTON_SEARCH, &CLogDialog::OnBnClickedButtonSearch)
	ON_WM_CREATE()
	//ON_CBN_SELCHANGE(IDC_COMBO_LEVEL, &CLogDialog::OnCbnSelchangeComboLevel)
	ON_BN_CLICKED(IDC_CHECK_ERROR, &CLogDialog::OnBnClickedRadioError)
	ON_BN_CLICKED(IDC_CHECK_DEBUG, &CLogDialog::OnBnClickedRadioDebug)
	ON_BN_CLICKED(IDC_CHECK_INFO, &CLogDialog::OnBnClickedRadioInfo)
	ON_BN_CLICKED(IDC_CHECK_ALL, &CLogDialog::OnBnClickedRadioAll)
	ON_BN_CLICKED(IDC_CHECK_IMPORTANT, &CLogDialog::OnBnClickedRadioImport)
END_MESSAGE_MAP()

// CLogDialog 消息处理程序

void CLogDialog::OnBnClickedButtonSearch()
{
	// TODO: 在此添加控件通知处理程序代码
	CString searchString;
	M_EditSearch.GetWindowText(searchString);
	//out << "searchString " << string(CT2A(searchString.GetString())) << endl;
	if (searchString.IsEmpty())
		return;
	int state = ((CButton*)GetDlgItem(IDC_CHECK_REG))->GetCheck();
	if (state == 1)//正则表达式搜索
	{
		string pattern =CT2A(searchString.GetString());
		try {
			regex reg(pattern);
			smatch sResult;
			//根据文本模糊搜索
			int total_count = m_LogViewList.GetItemCount();
			//out << "m_LogViewList total_count" << total_count << endl;
			for (int i = m_SearchIndex; i < total_count; i++)
			{
				CString itemStr = m_LogViewList.GetItemText(i, 0);
				string cmp_str = CT2A(itemStr.GetString());
				//out << "m_LogViewList item" << string(CT2A(itemStr))<<" searchString "<< string(CT2A(searchString)) << endl;
				if (regex_search(cmp_str, sResult, reg))//找到字符串
				{
					//out << "search iIndex" << i << endl;

					//跳转并滚动到搜索到的索引
					m_LogViewList.EnsureVisible(i, FALSE);//设置滚动条位置
					//设置焦点
					m_LogViewList.SetFocus();
					//设置选中某一行
					m_LogViewList.SetItemState(-1, 0, LVIS_SELECTED);
					m_LogViewList.SetItemState(i, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);//选中并聚焦
					m_SearchIndex = i + 1;
					break;
				}
			}
		}
		catch (std::regex_error& e)
		{
			out << "regex error " << e.what() << " error code " << e.code() << std::endl;
			AfxMessageBox(_T("正则表达式错误"));
		}
	}
	else
	{
		//根据文本模糊搜索
		int total_count = m_LogViewList.GetItemCount();
		//out << "m_LogViewList total_count" << total_count << endl;
		for (int i = m_SearchIndex; i < total_count; i++)
		{
			CString itemStr = m_LogViewList.GetItemText(i, 0);
			//out << "m_LogViewList item" << string(CT2A(itemStr))<<" searchString "<< string(CT2A(searchString)) << endl;
			if (itemStr.Find(searchString)>=0)//找到字符串
			{
				//out << "search iIndex" << i << endl;
				
				//跳转并滚动到搜索到的索引
				m_LogViewList.EnsureVisible(i, FALSE);//设置滚动条位置
				//设置焦点
				m_LogViewList.SetFocus();
				//设置选中某一行
				m_LogViewList.SetItemState(-1, 0, LVIS_SELECTED);
				m_LogViewList.SetItemState(i, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);//选中并聚焦
				m_SearchIndex = i+1;
				break;
			}
		}
#if 0
		LVFINDINFO lvFindInfo;
		lvFindInfo.flags = LVFI_PARTIAL;
		lvFindInfo.psz = searchString;
		int iIndex= m_LogViewList.FindItem(&lvFindInfo, m_SearchIndex);
		out << "search iIndex" << iIndex << endl;
		m_SearchIndex = iIndex;
		//跳转并滚动到搜索到的索引
		m_LogViewList.EnsureVisible(m_SearchIndex - 1, FALSE);//设置滚动条位置
#endif

	}
}
BOOL CLogDialog::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	clock_t start;
	clock_t end;
	//AfxMessageBox(_T("CLogDialog init"));
	m_SearchNext.ShowWindow(SW_HIDE);
	RECT rc;
	m_LogViewList.GetClientRect(&rc);
	m_StaticResult.ShowWindow(SW_HIDE);
	long width = (rc.right - rc.left);
	// TODO: 在此添加额外的初始化代码
	m_LogViewList.InsertColumn(0, _T("日志内容"), LVCFMT_LEFT, width);
	if (!m_FileDir.empty())
	{
		start = clock();
		int ret= parseLogByFile(m_FileDir,m_vLogRecord);
		end = clock();
		out << "total parse time used " << end - start << " ret = " << ret << endl;
		out << "m_vLogRecord size " << m_vLogRecord.size() << endl;
		if (!ret)
		{
			//将日志内容插入listctrl控件
			//vector<CLogRecord> vLogRecord;
			//FilterImportantVector(m_vLogShow);
			FilterLogVector();
			SetLogShow();
		}
	}
	return true;
}
int CLogDialog::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CDialogEx::OnCreate(lpCreateStruct) == -1)
		return -1;
	//AfxMessageBox(_T("CLogDialog create"));
	// TODO:  在此添加您专用的创建代码

	return 0;
}
void CLogDialog::FilterImportantVector(vector<CLogRecord>& vLogRecord)
{
	string pattern = "<Error>|([sS]olid\\[)|(file loaded:)|(点击)";
	try {
		regex reg(pattern);
		smatch sResult;
		for (auto it : m_vLogRecord)
		{
			//匹配成功加入容器
			string cmp_str = it.GetLogContent();
			if (regex_search(cmp_str, sResult, reg))
			{
				vLogRecord.push_back(it);
			}
		}
	}
	catch (std::regex_error& e)
	{
		out << "regex error " << e.what() << " error code " << e.code() << std::endl;
		AfxMessageBox(_T("regex error happened"));
	}
}
void CLogDialog::SetLogShow()
{
	clock_t start;
	clock_t end;
	CString strContent;
	int i = 0;
	start = clock();
	m_LogViewList.SetRedraw(FALSE);
	m_LogViewList.DeleteAllItems();
	m_LogViewList.InitSet();
	for (auto it : m_vLogShow)
	{

		strContent = CString(it.GetLogContent().c_str());
		m_LogViewList.InsertItem(i, _T(""));
		m_LogViewList.SetItemText(i, 0, strContent);
		if (it.GetLogLevel() == LEVEL_INFO)
		{
			//普通info直接黑色字体
		}
		else if (it.GetLogLevel() == LEVEL_DEBUG)
		{
			//DEBUG蓝色字体
			m_LogViewList.SetFontColor(i, 0, RGB(0, 0, 255));
		}
		else if (it.GetLogLevel() == LEVEL_ERROR)
		{
			//ERROR红色字体
			m_LogViewList.SetFontColor(i, 0, RGB(255, 0, 0));
		}
		i++;
	}
	m_LogViewList.SetRedraw(TRUE);
	end = clock();
	out << "total show log used time" << end - start << endl;
}
void CLogDialog::FilterLogVector( )
{
	m_vLogShow.clear();
	m_SearchIndex = 0;
	if (m_FilterLevel == LV_ALL)
	{
		m_vLogShow = m_vLogRecord;
		return;
	}
	if (m_FilterLevel == LV_IMPORTANT)
	{
		FilterImportantVector(m_vLogShow);
		return;
	}
	for (auto it : m_vLogRecord)
	{
		if (m_FilterLevel & LV_INFO)
		{
			if (it.GetLogLevel() == LEVEL_INFO)
				m_vLogShow.push_back(it);
		}
		if (m_FilterLevel & LV_DEBUG)
		{
			if (it.GetLogLevel() == LEVEL_DEBUG)
				m_vLogShow.push_back(it);
		}
		if (m_FilterLevel & LV_ERROR)
		{
			if (it.GetLogLevel() == LEVEL_ERROR)
				m_vLogShow.push_back(it);
		}
	}
}
void CLogDialog::OnBnClickedRadioError()
{
	// TODO: 在此添加控件通知处理程序代码
	if (m_RadioError.GetCheck())
		m_FilterLevel |= LV_ERROR;
	else
		m_FilterLevel &= ~LV_ERROR;
	FilterLogVector();
	SetLogShow();
}

void CLogDialog::OnBnClickedRadioDebug()
{
	// TODO: 在此添加控件通知处理程序代码
	if (m_RadioDebug.GetCheck())
		m_FilterLevel |= LV_DEBUG;
	else
		m_FilterLevel &= ~LV_DEBUG;
	FilterLogVector();
	SetLogShow();
}

void CLogDialog::OnBnClickedRadioInfo()
{
	if (m_RadioInfo.GetCheck())
		m_FilterLevel |= LV_INFO;
	else
		m_FilterLevel &= ~LV_INFO;
	FilterLogVector();
	SetLogShow();
}

void CLogDialog::OnBnClickedRadioAll()
{
	// TODO: 在此添加控件通知处理程序代码
	if (m_RadioAll.GetCheck()) {
		m_FilterLevel = LV_ALL;
		m_RadioInfo.SetCheck(0);
		m_RadioError.SetCheck(0);
		m_RadioDebug.SetCheck(0);
		m_RadioImport.SetCheck(0);
		m_RadioInfo.EnableWindow(0);
		m_RadioError.EnableWindow(0);
		m_RadioDebug.EnableWindow(0);
		m_RadioImport.EnableWindow(0);
	}
	else
	{
		m_RadioInfo.EnableWindow(1);
		m_RadioError.EnableWindow(1);
		m_RadioDebug.EnableWindow(1);
		m_RadioImport.EnableWindow(1);
	}
	FilterLogVector();
	SetLogShow();
}



void CLogDialog::OnBnClickedRadioImport()
{
	// TODO: 在此添加控件通知处理程序代码
	if (m_RadioImport.GetCheck()) {
		m_FilterLevel = LV_IMPORTANT;
		m_RadioInfo.SetCheck(0);
		m_RadioError.SetCheck(0);
		m_RadioDebug.SetCheck(0);
		m_RadioAll.SetCheck(0);
		m_RadioInfo.EnableWindow(0);
		m_RadioError.EnableWindow(0);
		m_RadioDebug.EnableWindow(0);
		m_RadioAll.EnableWindow(0);
	}
	else
	{
		m_FilterLevel = LV_ALL;
		m_RadioInfo.EnableWindow(1);
		m_RadioError.EnableWindow(1);
		m_RadioDebug.EnableWindow(1);
		m_RadioAll.EnableWindow(1);
	}
	FilterLogVector();
	SetLogShow();
}
